home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / jikes / src / long.cpp < prev    next >
C/C++ Source or Header  |  1999-05-14  |  15KB  |  627 lines

  1. // $Id: long.cpp,v 1.4 1999/02/10 14:53:01 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <iostream.h>
  12. #include "long.h"
  13. #include "double.h"
  14. //
  15. // Note that the minimum long value, (0x80000000, 0x00000000), can be represented
  16. // exactly in a double field. However, the maximum long value, (0x7FFFFFFF, 0xFFFFFFFF)
  17. // cannot. To test if the double quantity "a" fits in a long range we will test whether
  18. // or not:
  19. //         (a >= min_long) && (-a > min_long)
  20. // 
  21. BaseLong::operator LongInt()
  22. {
  23.     return LongInt(HighWord(), LowWord());
  24. }
  25.  
  26. BaseLong::operator ULongInt()
  27. {
  28.     return ULongInt(HighWord(), LowWord());
  29. }
  30.  
  31. bool BaseLong::operator== (BaseLong op)
  32. {
  33.     return ((HighWord() == op.HighWord()) && (LowWord() == op.LowWord()));
  34. }
  35.  
  36. bool BaseLong::operator!= (BaseLong op)
  37. {
  38.     return ((HighWord() != op.HighWord()) || (LowWord() != op.LowWord()));
  39. }
  40.  
  41. bool BaseLong::operator!()
  42. {
  43.     return (*this == 0);
  44. }
  45.  
  46. BaseLong BaseLong::operator~()
  47. {
  48.     return BaseLong(~HighWord(), ~LowWord());
  49. }
  50.  
  51. BaseLong BaseLong::operator^ (BaseLong op)
  52. {
  53.     return BaseLong(HighWord() ^ op.HighWord(), LowWord() ^ op.LowWord());
  54. }
  55.  
  56. BaseLong& BaseLong::operator^= (BaseLong op)
  57. {
  58.     *this = *this ^ op;
  59.     return *this;
  60. }
  61.  
  62. BaseLong BaseLong::operator| (BaseLong op)
  63. {
  64.     return BaseLong(HighWord() | op.HighWord(), LowWord() | op.LowWord());
  65. }
  66.  
  67. BaseLong& BaseLong::operator|= (BaseLong op)
  68. {
  69.     *this = *this | op;
  70.     return *this;
  71. }
  72.  
  73. BaseLong BaseLong::operator& (BaseLong op)
  74. {
  75.     return BaseLong(HighWord() & op.HighWord(), LowWord() & op.LowWord());
  76. }
  77.  
  78. BaseLong& BaseLong::operator&= (BaseLong op)
  79. {
  80.     *this = *this & op;
  81.     return *this;
  82. }
  83.  
  84. bool BaseLong::operator&& (BaseLong op)
  85. {
  86.     return (*this != 0) && (op != 0);
  87. }
  88.  
  89. bool BaseLong::operator|| (BaseLong op)
  90. {
  91.     return (*this != 0) || (op != 0);
  92. }
  93.  
  94. BaseLong BaseLong::operator<< (BaseLong op)
  95. {
  96.     u4 n = op.LowWord(); // Always treat this value as positive, since negative values are not allowed
  97.  
  98.     //
  99.     // Note that this function assumes that for two 32-bit integers
  100.     // x << y, where y = 0, is well-defined and that the result is
  101.     // the value x. This is true in Ansi-C and C++ but not true in
  102.     // old versions of C (See Kernighan and Ritchie).
  103.     // Note also that in shifting a 32-bit word, if y >= 32 then the
  104.     // result is unpredictable. On Aix, xlC will produce the result 0(good!)
  105.     // whereas on windows the Microsoft compiler produces the value of x(very bad !).
  106.     // That is the reason why we have the initial special check for (n == 0).
  107.     //
  108.  
  109.     if(n == 0)
  110.         return *this;
  111.     else if(n < 32)
  112.         return BaseLong((HighWord() << n) |
  113.             (LowWord() >> (32 - n)), LowWord() << n);
  114.     else
  115.         return BaseLong(LowWord() << (n - 32), 0);
  116. }
  117.  
  118. BaseLong& BaseLong::operator<<= (BaseLong op)
  119. {
  120.     *this = *this << op;
  121.     return *this;
  122. }
  123.  
  124. BaseLong BaseLong::operator+ (BaseLong op)
  125. {
  126.     u4 ushort1 = (LowWord() & 0xFFFF) + (op.LowWord() & 0xFFFF),
  127.     ushort2 = (ushort1 >> 16) + (LowWord() >> 16) + (op.LowWord() >> 16),
  128.     ushort3 = (ushort2 >> 16) + (HighWord() & 0xFFFF) + (op.HighWord() & 0xFFFF),
  129.     ushort4 = (ushort3 >> 16) + (HighWord() >> 16) + (op.HighWord() >> 16);
  130.  
  131.     return BaseLong((ushort3 & 0xFFFF) | (ushort4 << 16), (ushort1 & 0xFFFF) | (ushort2 << 16));
  132. }
  133.  
  134. BaseLong& BaseLong::operator+= (BaseLong op)
  135. {
  136.     *this = *this + op;
  137.     return *this;
  138. }
  139.  
  140. BaseLong BaseLong::operator++ (int dummy)
  141. {
  142.     BaseLong temp = *this;
  143.     *this += 1;
  144.     return temp;
  145. }
  146.  
  147. BaseLong BaseLong::operator++ ()
  148. {
  149.     *this += 1;
  150.     return *this;
  151. }
  152.  
  153. BaseLong BaseLong::operator- ()
  154. {
  155.     return ~(*this) + 1;
  156. }
  157.  
  158. BaseLong BaseLong::operator- (BaseLong op)
  159. {
  160.     return *this + (-op);
  161. }
  162.  
  163. BaseLong& BaseLong::operator-= (BaseLong op)
  164. {
  165.     *this = *this - op;
  166.     return *this;
  167. }
  168.  
  169. BaseLong BaseLong::operator-- (int dummy)
  170. {
  171.     BaseLong temp = *this;
  172.     *this -= 1;
  173.     return temp;
  174. }
  175.  
  176. BaseLong BaseLong::operator-- ()
  177. {
  178.     *this -= 1;
  179.     return *this;
  180. }
  181.  
  182. BaseLong BaseLong::operator* (BaseLong op)
  183. {
  184.     u4 x0 = this -> LowWord()   & 0xFFFF,
  185.     x1 = this -> LowWord()  >> 16,
  186.     x2 = this -> HighWord()  & 0xFFFF,
  187.     x3 = this -> HighWord() >> 16;
  188.  
  189.     u4 y0 = op.LowWord()   & 0xFFFF,
  190.     y1 = op.LowWord()  >> 16,
  191.     y2 = op.HighWord()  & 0xFFFF,
  192.     y3 = op.HighWord() >> 16;
  193.  
  194.     BaseLong result = BaseLong(0, x0 * y0);
  195.     BaseLong part1  = BaseLong(0, x0 * y1);
  196.     part1  <<= (1 << 4);
  197.     result += part1;
  198.     BaseLong part2  = BaseLong(0, x0 * y2);
  199.     part2  <<= (2 << 4);
  200.     result += part2;
  201.     BaseLong part3  = BaseLong(0, x0 * y3);
  202.     part3  <<= (3 << 4);
  203.     result += part3;
  204.  
  205.     BaseLong part4  = BaseLong(0, x1 * y0);
  206.     part4  <<= (1 << 4);
  207.     result += part4;
  208.     BaseLong part5  = BaseLong(0, x1 * y1);
  209.     part5  <<= (2 << 4);
  210.     result += part5;
  211.     BaseLong part6  = BaseLong(0, x1 * y2);
  212.     part6  <<= (3 << 4);
  213.     result += part6;
  214.     BaseLong part7  = BaseLong(0, x1 * y3);
  215.     part7  <<= (4 << 4);
  216.     result += part7;
  217.  
  218.     BaseLong part8  = BaseLong(0, x2 * y0);
  219.     part8  <<= (2 << 4);
  220.     result += part8;
  221.     BaseLong part9  = BaseLong(0, x2 * y1);
  222.     part9  <<= (3 << 4);
  223.     result += part9;
  224.     BaseLong part10 = BaseLong(0, x2 * y2);
  225.     part10 <<= (4 << 4);
  226.     result += part10;
  227.     BaseLong part11 = BaseLong(0, x2 * y3);
  228.     part11 <<= (5 << 4);
  229.     result += part11;
  230.  
  231.     BaseLong part12 = BaseLong(0, x3 * y0);
  232.     part12 <<= (3 << 4);
  233.     result += part12;
  234.     BaseLong part13 = BaseLong(0, x3 * y1);
  235.     part13 <<= (4 << 4);
  236.     result += part13;
  237.     BaseLong part14 = BaseLong(0, x3 * y2);
  238.     part14 <<= (5 << 4);
  239.     result += part14;
  240.     BaseLong part15 = BaseLong(0, x3 * y3);
  241.     part15 <<= (6 << 4);
  242.     result += part15;
  243.  
  244.     return result;
  245. }
  246.  
  247. BaseLong& BaseLong::operator*= (BaseLong op)
  248. {
  249.     *this = *this * op;
  250.     return *this;
  251. }
  252.  
  253.  
  254. BaseLong::BaseLong(u4 a, u4 b)
  255. {
  256.     HighWord() = a;
  257.     LowWord() = b;
  258. }
  259.  
  260. BaseLong::BaseLong(u4 a)
  261. {
  262.     HighWord() = 0;
  263.     LowWord() = a;
  264. }
  265.  
  266. BaseLong::BaseLong(i4 a)
  267. {
  268.     LowWord() = a;
  269.     //
  270.     // Since the carry is not guaranteed to ripple, we cannot use this code.
  271.     //
  272.     //        HighWord() = a >> 31;
  273.     //
  274.     HighWord() = (a < 0 ? 0xFFFFFFFF : 0x00000000);
  275. }
  276.  
  277.  
  278. void BaseLong::Divide(BaseLong dividend, BaseLong divisor, BaseLong "ient, BaseLong &remainder)
  279. {
  280.     u4 high = dividend.HighWord(),
  281.        low  = dividend.LowWord(),
  282.        remainder_high = 0;
  283.  
  284.     for (int i = 0; i < 32; i++)
  285.     {
  286.         remainder_high = (remainder_high << 1) | (high >> 31);
  287.         high <<= 1;
  288.         if ((ULongInt) divisor <= remainder_high)
  289.         {
  290.             high++;
  291.             remainder_high -= divisor.LowWord();
  292.         }
  293.     }
  294.  
  295.     remainder = BaseLong(0, remainder_high);
  296.  
  297.     for (int j = 0; j < 32; j++)
  298.     {
  299.         remainder <<= 1;
  300.         remainder.LowWord() |= (low >> 31);
  301.         low <<= 1;
  302.         if ((ULongInt) divisor <= remainder)
  303.         {
  304.             low++;
  305.             remainder -= divisor;
  306.         }
  307.     }
  308.  
  309.     quotient = BaseLong(high, low);
  310.  
  311.     return;
  312. }
  313.  
  314.  
  315. void ULongInt::String(char *result)
  316. {
  317.     ULongInt val = *this;
  318.     char *ptr = result;
  319.  
  320.     do
  321.     {
  322.         *ptr++ = '0' + (val % 10).LowWord();
  323.         val /= 10;
  324.     } while (val != 0);
  325.  
  326.     *ptr = U_NULL;
  327.  
  328.     for (char *tail = ptr - 1; tail > result; tail--, result++)
  329.     {
  330.         char c = *tail;
  331.         *tail = *result;
  332.         *result = c;
  333.     }
  334.  
  335.     return;
  336. }
  337.  
  338.  
  339. void LongInt::String(char *result)
  340. {
  341.     ULongInt val;
  342.  
  343.     if (HighWord() & 0x80000000)
  344.     {
  345.         *result++ = '-';
  346.         val = -(*this);
  347.     }
  348.     else val = *this;
  349.  
  350.     val.String(result);
  351.  
  352.     return;
  353. }
  354.  
  355. ULongInt& ULongInt::operator/= (ULongInt op)
  356. {
  357.     *this = *this / op;
  358.     return *this;
  359. }
  360.  
  361.  
  362. ULongInt ULongInt::operator/ (ULongInt op)
  363. {
  364.     BaseLong quotient,
  365.     remainder;
  366.  
  367.     Divide(*this, op, quotient, remainder);
  368.  
  369.     return quotient;
  370. }
  371.  
  372. ULongInt ULongInt::operator% (ULongIn